// DEPRECATED
import React from 'react';
import axios from 'axios';
import BpmnModeler from 'bpmn-js/lib/Modeler';
import {
  Layout, Modal, Upload, Button, Icon, Input, Form, message, Cascader,
} from 'antd';
import { createProcess } from 'services/process';
import 'assets/css/bpmn.css';

import 'bpmn-js/dist/assets/diagram-js.css';
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
// use mockjs to mock data exchange
import 'mock/GetServiceMock';
// import '../../../mock/UploadBpmnMock';

import BpmnExtension from 'assets/BpmnExtension.json';


const { Content } = Layout;
const ContentStyle = {
  background: '#fff',
  padding: 24,
  margin: 0,
  minHeight: 280,
};


let inputRef = null;
let paramRef = [];
let availableServices = [];
let modeler;
let diagramXML;
let chosenId;
let chosenElement;
let moddle;
let elementRegistry;
let modeling;
let chosenService;
let chosenInterface;
let chosenUrl;
let selectOptions;
let params = [];
let enableOk = true;

export default class ProcessDesign extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      visible: false,
      text: '',
      showParam: false,
    };
  }

  convertToOptions = (data) => data.map((item, i) => {
    const re = {};
    re.value = (i).toString();
    re.label = item.serviceName;
    re.children = item.interface.map((interfaceItem, j) => {
      const reInterface = {};
      reInterface.value = `${(i).toString()}-${(j).toString()}`;
      reInterface.label = interfaceItem.interfaceName;
      return reInterface;
    });
    return re;
  })

    showModal = () => {
      this.setState({
        visible: true,
      });
    };

    handleOk = () => {
      this.setState({
        visible: false,
      });
      chosenElement = elementRegistry.get(chosenId);
      const extensionElements = moddle.create('bpmn:ExtensionElements');
      const propertyService = moddle.create('camunda:property');
      propertyService.name = 'serviceName';
      const propertyName = moddle.create('camunda:property');
      propertyName.name = 'interfaceName';
      const propertyUrl = moddle.create('camunda:property');
      propertyUrl.name = 'interfaceUrl';
      const propertyParam = moddle.create('camunda:property');
      propertyParam.name = 'params';


      params.forEach((o, i) => {
        const temp = moddle.create('camunda:property');
        temp.name = o;
        temp.value = paramRef[i].input.value;
        propertyParam.get('subproperty').push(temp);
      });

      propertyService.value = chosenService;
      propertyName.value = chosenInterface;
      propertyUrl.value = chosenUrl;

      const properties = moddle.create('camunda:properties');
      properties.get('subproperty').push(propertyService);
      properties.get('subproperty').push(propertyName);
      properties.get('subproperty').push(propertyUrl);
      properties.get('subproperty').push(propertyParam);
      extensionElements.get('values').push(properties);

      modeling.updateProperties(chosenElement, {
        name: `${chosenService}\n${chosenInterface}`,
        extensionElements,
      });
      this.setState({ text: '' });
      paramRef = [];
      params = [];
      enableOk = true;
    };

    handleCancel = () => {
      this.setState({
        visible: false,
        text: '',
        showParam: false,
      });
      enableOk = true;
    };

    handleUpload = (f) => {
      const formData = new FormData();
      formData.append('name', f.file.name);
      formData.append('file', f.file);
      createProcess(formData).then(message.success('上传成功'));
      // for local test
      // axios
      //   .post('/process/uploadBpmn', formData, {
      //     headers: {
      //       Authorization: localStorage.getItem('Token'),
      //     },
      //   })
      //   .then((response) => {
      //     if (response.data.status === '200') {
      //       message.success(response.data.message);
      //     } else {
      //       message.error(response.data.message);
      //     }
      //   })
      //   .catch((error) => console.error('Error:', error));
    }


    openDiagram = (bpmnXML) => {
      fetch(bpmnXML).then((response) => response.text().then((text) => {
        // this.setState({ diagramXML: text });
        diagramXML = text;
        modeler.importXML(diagramXML, (err) => {
          if (err) {
            message.error('error rendering', err);
          } else {
            const canvas = modeler.get('canvas');
            // zoom to fit full viewport
            canvas.zoom('fit-viewport');
          }
        });
      }));
    }

    // 在一开始就直接渲染，将text展示于框中
    displayRender = () => {
      const { text } = this.state;
      return text;
    }


    // 在选择完成后的回调，将需要展示的字符串写入状态text里
    onChange = (value, selectedOptions) => {
      chosenService = selectedOptions[0].label;
      chosenInterface = selectedOptions[1].label;
      const temp = selectedOptions.map((item, i) => {
        if (i === 0) return `微服务:${item.label}, `;
        if (i === 1) return `接口:${item.label}`;
        return '';
      });

      availableServices.forEach((service) => {
        if (service.serviceName === chosenService) {
          service.interface.forEach((item) => {
            if (item.interfaceName === chosenInterface) {
              chosenUrl = item.url;
              params = item.param.map((o) => o.paramName);
            }
          });
        }
      });
      this.setState({
        text: temp,
        showParam: true,
      });
      enableOk = false;
    };


    exportDiagram = () => {
      const This = this;
      modeler.saveXML({ format: true }, (err, xml) => {
        if (err) {
          console.error('could not save BPMN 2.0 diagram', err);
        }
        const file = new File([xml], inputRef.input.value, {
          type: 'text/plain',
        });
        const formData = new FormData();
        formData.append('name', inputRef.input.value);
        formData.append('file', file);
        createProcess(formData).then(() => {
          message.success('上传成功');
          This.openDiagram('/BpmnXML.bpmn');
          inputRef.input.value = '';
        });
      });
    }


    componentDidMount() {
      modeler = new BpmnModeler({
        container: '#canvas',
        moddleExtensions: {
          camunda: BpmnExtension,
        },
      });
      this.openDiagram('/BpmnXML.bpmn');

      const eventBus = modeler.get('eventBus');
      elementRegistry = modeler.get('elementRegistry');
      modeling = modeler.get('modeling');
      const directEditing = modeler.get('directEditing');
      moddle = modeler.get('moddle');

      const This = this;
      eventBus.on('create.end', 250, () => {
        directEditing.cancel();
      });
      eventBus.on('element.dblclick', 1500, (e) => {
        // e.element = the model element
        if (e.element.type === 'bpmn:Task' || e.element.type === 'bpmn:UserTask') {
          This.showModal();
          chosenId = e.element.id;
        }
        e.stopPropagation();
      });

      axios
        .post(
          '/process/getService',
          {
            headers: {
              Authorization: localStorage.getItem('Token'),
            },
          },
        )
        .then((response) => {
          if (response.data.status === '200') {
            availableServices = response.data.data;
            selectOptions = this.convertToOptions(availableServices);
          } else {
            message.error(response.data.message);
          }
        })
        .catch((error) => console.error('Error:', error));
    }

    render() {
      paramRef = [];
      const { visible, showParam } = this.state;
      let paramForm;
      if (showParam === true) {
        paramForm = params.map((item, i) => (
          <Form.Item label={item} style={{ margin: '8px' }}>
            <Input ref={(input) => { paramRef[i] = input; }} />
          </Form.Item>
        ));
      }


      return (
        <>
          <Content style={ContentStyle}>
            <div id="canvas" style={{ height: '500px' }} />
          </Content>
          <Modal
            title="可选微服务接口"
            visible={visible}
            onOk={this.handleOk}
            onCancel={this.handleCancel}
            destroyOnClose
            okButtonProps={{ disabled: enableOk }}
          >

            <Cascader size="large" style={{ width: '100%' }} options={selectOptions} displayRender={this.displayRender} onChange={this.onChange} placeholder="选择微服务接口" allowClear={false} />
            {showParam === true
              ? (
                <Form>
                  {paramForm}
                </Form>
              ) : null}
          </Modal>
          <Form layout="inline">
            <Form.Item>
              <Input
                ref={(input) => { inputRef = input; }}
                prefix={<Icon type="file" style={{ color: 'rgba(0,0,0,.25)' }} />}
                placeholder="文件名"
              />
            </Form.Item>
            <Form.Item>
              <Button type="default" htmlType="submit" onClick={this.exportDiagram}>
                  保存BPMN文件
              </Button>
            </Form.Item>
          </Form>
          <Upload
            customRequest={this.handleUpload}
            showUploadList={false}
          >
            <Button>
              <Icon type="upload" />
                   上传BPMN文件
            </Button>
          </Upload>
        </>
      );
    }
}
